function [OUT_Symbols_final OUT_Channel] = MMSE_DFE_Equalizer(Current_Frame_toEqualize, Current_Tranining_toEqualize,...
    Data_After, Oversample, EsNoRatio, Original_Current_Frame, Rate, Hard, N1, N2)


%%
% ************************************************************* %
% ********************** Parameters ****************************** %
% ************************************************************* %
Training_Length = 31;
Data_Length = 256;
N = N1+N2+1;

estimation_length = 31*Oversample;     % window of estimation (for mini-probe and data)
ChLength = 6*Oversample;               % supposed channel length for estimation
% ************************************************************* %

% ************************************************************* %
% ************************** Filter ****************************** %
% ************************************************************* %
Filter_Length = 12;  
Rolloff = 0.385;      

HF_SRRC = rcosfir(Rolloff,Filter_Length/2,Oversample,1,'sqrt');
HF_SRRC_TX_RX = conv(HF_SRRC,HF_SRRC);

%------------------------ DownSampling for Input Data --------------------%
Current_Frame_toEqualize_Symbols = Current_Frame_toEqualize(1:Oversample:end);
Original_Current_Frame_Symbols = Original_Current_Frame(1:Oversample:end);
%*------------------------------------------------------------------------%

%*--------------------------- Prepare the data to the Equalizer ----------%
Original_Symbols_BeforeAndAfter_Symbols = Original_Current_Frame_Symbols(Training_Length-N2:end-N1+1);
Original_Symbols_BeforeAndAfter = Original_Current_Frame((Training_Length-N2)*Oversample+1:end-N1*Oversample+1);

IN_Frame_toEqualizer = [Current_Tranining_toEqualize(end-N2*Oversample+1-3:end),...
    Current_Frame_toEqualize,...
    Data_After(1:N1*Oversample)];

Hard_Decision_Symbols = Original_Symbols_BeforeAndAfter_Symbols(1:N2+1);
Hard_Decision_Symbols_Samples1 = conv(upsample(Hard_Decision_Symbols,Oversample),HF_SRRC_TX_RX);
Hard_Decision_Symbols_Samples = Hard_Decision_Symbols_Samples1(length(HF_SRRC)+Oversample:end-length(HF_SRRC)+1);
%*------------------------------------------------------------------------%


%-*------------- Channel Estimation for Start Mini-Probe -----------------%
ChOutput(1,:) = Current_Tranining_toEqualize(end-estimation_length+1:end);
ChInput(1,:) = Original_Current_Frame(Training_Length*Oversample-estimation_length+1:Training_Length*Oversample);

[Estimated_Channel(:,1),error(1)] = HF_LSChEstimateSubtacting_modified(ChOutput(1,:),ChInput(1,:),ChLength);
Estimated_Channel_start = [Estimated_Channel(1:21,1)];

%*-------------- Channel Estimation for the END Mini-Probe ---------------%
ChOutput_end = Data_After(1:estimation_length);
ChInput_end = Original_Current_Frame((Training_Length+Data_Length)*Oversample+1:(Training_Length+Data_Length)*Oversample+estimation_length);

[Estimated_Channel_end,error_end] = HF_LSChEstimateSubtacting_modified(ChOutput_end,ChInput_end,ChLength);
Estimated_Channel_end = [Estimated_Channel_end(1:21)];
Estimated_Channel_end = Estimated_Channel_end(:);


for ch_index = 1:21
    Interpolated_Channel(ch_index,:) = interp1([1 Data_Length], [Estimated_Channel_start(ch_index) Estimated_Channel_end(ch_index)], (1:Data_Length),'linear','extrap');
end

Interpolated_Channel(:,1:end-8) = Interpolated_Channel(:,9:end);

for index = 1:length(Current_Frame_toEqualize_Symbols)
    
    if mod(index-1,16) == 0
        [H H_herm s I_N I_N1_1 Hff Hff_herm sff Vff Hfb Hfb_herm] = Generate_H_Fractional(Interpolated_Channel(:,index),N*Oversample,N1*Oversample,N2*Oversample,Oversample);

        f_ff(index,:) = inv( Hff*Vff*Hff_herm + 1/(EsNoRatio)*I_N1_1 )*sff;
        f_ff_T = f_ff(index,:).';
        
        f_fb(index,:) = -Hfb_herm*f_ff_T;
        f_fb_T = f_fb(index,:).';
    else
        f_ff(index,:) = f_ff(index-1,:);
        f_fb(index,:) = f_fb(index-1,:);
    end
    
    zff = fliplr(IN_Frame_toEqualizer((index+N2-1)*Oversample+1:(index+N-1)*Oversample));
    zff_T = zff.';
    
    if Hard == 1
        xn = fliplr(Hard_Decision_Symbols_Samples((index-1)*Oversample+1:(index+N2-1)*Oversample));
    else
        xn = fliplr(Original_Symbols_BeforeAndAfter((index-1)*Oversample+1:(index+N2-1)*Oversample));
    end
    
    xn_T = xn.';
    
    OUT_Symbols(index) = f_ff_T'*zff_T + f_fb_T'*xn_T;
    
    Hard_Decision_Symbols(N2+index+1) = 1*HF_Modulate(HF_Demodulate(OUT_Symbols(index),Rate),Rate);
    
    Hard_Decision_Symbols_Samples1=conv(upsample(Hard_Decision_Symbols,Oversample),HF_SRRC_TX_RX);
    Hard_Decision_Symbols_Samples = Hard_Decision_Symbols_Samples1(length(HF_SRRC)+Oversample:end-length(HF_SRRC)+1);
    
end

OUT_Channel = Interpolated_Channel;

OUT_Symbols_final = OUT_Symbols;


end















